#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
火山方舟 TTS 单个文本语音生成脚本
支持指定文字生成到 tmp/voice 文件夹

使用方法：
1. 设置环境变量：
   export VOLC_APPID="你的appid"
   export VOLC_ACCESS_TOKEN="你的access_token"  
   export VOLC_CLUSTER="你的cluster"
   export VOLC_VOICE_TYPE="你的voice_type"

2. 运行脚本：
   python3 scripts/generate_tts_text.py "要合成的文字"

可选参数：
   --text TEXT         要合成的文字（必需）
   --format FORMAT    音频格式 mp3/wav (默认: mp3)
   --speed SPEED      语速比例 0.5-2.0 (默认: 1.0)
   --volume VOLUME    音量比例 0.5-2.0 (默认: 1.0)  
   --pitch PITCH      音调比例 0.5-2.0 (默认: 1.0)
   --filename NAME    输出文件名（不含扩展名，默认使用文字生成）
   --output-dir DIR   输出目录（默认: tmp/voice）
"""

import argparse
import base64
import json
import os
import re
import sys
import uuid
from pathlib import Path
from typing import Dict, Optional


def slugify(text: str) -> str:
    """将文本转换为安全的文件名"""
    # 移除或替换特殊字符
    text = re.sub(r'[<>:"/\\|?*]', '', text)
    text = re.sub(r'\s+', '_', text.strip())
    return text[:50]  # 限制长度


def synthesize_text(
    text: str,
    voice_config: Dict,
    output_dir: Path,
    filename: Optional[str] = None,
    format: str = 'mp3'
) -> bool:
    """
    合成指定文本的语音
    
    Returns:
        success: bool
    """
    # 生成文件名
    if filename:
        slug = slugify(filename)
    else:
        slug = slugify(text)
    
    out_path = output_dir / f"{slug}.{format}"
    
    print(f"[准备合成] text='{text}' -> {out_path.resolve()}")
    
    try:
        # 构建请求
        request_json = {
            "app": {
                "appid": voice_config['appid'],
                "token": "access_token",  # 固定值
                "cluster": voice_config['cluster']
            },
            "user": {
                "uid": "388808087185088"  # 固定值
            },
            "audio": {
                "voice_type": voice_config['voice_type'],
                "encoding": format,
                "speed_ratio": voice_config['speed'],
                "volume_ratio": voice_config['volume'],
                "pitch_ratio": voice_config['pitch'],
            },
            "request": {
                "reqid": str(uuid.uuid4()),
                "text": text,
                "text_type": "plain",
                "operation": "query",
                "with_frontend": 1,
                "frontend_type": "unitTson"
            }
        }
        
        headers = {
            "Authorization": f"Bearer;{voice_config['access_token']}",
            "Content-Type": "application/json"
        }
        
        print(f"[请求] endpoint={voice_config['api_url']} voice_type={voice_config['voice_type']} format={format}")
        
        # 发送请求
        import requests
        response = requests.post(
            voice_config['api_url'],
            data=json.dumps(request_json),
            headers=headers,
            timeout=30
        )
        
        if response.status_code != 200:
            error_msg = f"HTTP {response.status_code}: {response.text}"
            print(f"[生成失败] text='{text}' -> {out_path.resolve()} | reason=TTS 请求失败 {error_msg}")
            return False
        
        # 解析响应
        result = response.json()
        
        if "data" not in result:
            error_msg = f"响应中无 data 字段: {result}"
            print(f"[生成失败] text='{text}' -> {out_path.resolve()} | reason={error_msg}")
            return False
        
        # 解码并保存音频数据
        audio_data = base64.b64decode(result["data"])
        
        # 确保输出目录存在
        out_path.parent.mkdir(parents=True, exist_ok=True)
        
        # 写入文件
        with open(out_path, 'wb') as f:
            f.write(audio_data)
        
        print(f"[生成成功] text='{text}' -> {out_path.resolve()} | size={len(audio_data)} bytes")
        return True
        
    except Exception as e:
        error_msg = f"异常: {str(e)}"
        print(f"[生成失败] text='{text}' -> {out_path.resolve()} | reason={error_msg}")
        return False


def main():
    parser = argparse.ArgumentParser(description='火山方舟 TTS 单个文本语音生成')
    parser.add_argument('text', nargs='?', help='要合成的文字')
    parser.add_argument('--format', default='mp3', choices=['mp3', 'wav'], help='音频格式')
    parser.add_argument('--speed', type=float, default=1.0, help='语速比例 (0.5-2.0)')
    parser.add_argument('--volume', type=float, default=1.0, help='音量比例 (0.5-2.0)')
    parser.add_argument('--pitch', type=float, default=1.0, help='音调比例 (0.5-2.0)')
    parser.add_argument('--filename', help='输出文件名（不含扩展名）')
    parser.add_argument('--output-dir', default='tmp/voice', help='输出目录')
    
    args = parser.parse_args()
    
    # 获取要合成的文字
    if args.text:
        text = args.text
    else:
        # 从标准输入读取
        print("请输入要合成的文字（按 Ctrl+D 结束输入）：")
        try:
            text = sys.stdin.read().strip()
        except KeyboardInterrupt:
            print("\n已取消")
            sys.exit(0)
        except EOFError:
            print("\n未输入文字")
            sys.exit(1)
    
    if not text:
        print("✗ 请提供要合成的文字")
        parser.print_help()
        sys.exit(1)
    
    # 检查环境变量
    required_env = ['VOLC_APPID', 'VOLC_ACCESS_TOKEN', 'VOLC_CLUSTER', 'VOLC_VOICE_TYPE']
    missing_env = [env for env in required_env if not os.getenv(env)]
    
    if missing_env:
        print(f"✗ 缺少必需的环境变量: {', '.join(missing_env)}")
        print("\n请设置以下环境变量：")
        print("export VOLC_APPID=\"你的appid\"")
        print("export VOLC_ACCESS_TOKEN=\"你的access_token\"")
        print("export VOLC_CLUSTER=\"你的cluster\"")
        print("export VOLC_VOICE_TYPE=\"你的voice_type\"")
        sys.exit(1)
    
    # 配置参数
    voice_config = {
        'appid': os.getenv('VOLC_APPID'),
        'access_token': os.getenv('VOLC_ACCESS_TOKEN'),
        'cluster': os.getenv('VOLC_CLUSTER'),
        'voice_type': os.getenv('VOLC_VOICE_TYPE'),
        'api_url': os.getenv('VOLC_TTS_ENDPOINT', 'https://openspeech.bytedance.com/api/v1/tts'),
        'format': args.format,
        'speed': args.speed,
        'volume': args.volume,
        'pitch': args.pitch,
    }
    
    print(f"🎵 火山方舟 TTS 文本合成")
    print(f"   text: '{text}'")
    print(f"   appid: {voice_config['appid']}")
    print(f"   cluster: {voice_config['cluster']}")
    print(f"   voice_type: {voice_config['voice_type']}")
    print(f"   format: {voice_config['format']}")
    print(f"   speed: {voice_config['speed']}")
    print(f"   volume: {voice_config['volume']}")
    print(f"   pitch: {voice_config['pitch']}")
    print()
    
    # 路径设置
    project_root = Path(__file__).parent.parent
    output_dir = project_root / args.output_dir
    
    # 合成语音
    success = synthesize_text(
        text=text,
        voice_config=voice_config,
        output_dir=output_dir,
        filename=args.filename,
        format=args.format
    )
    
    if success:
        print(f"\n🎉 语音文件生成完成！")
        print(f"   📁 文件路径: {output_dir.resolve()}")
    else:
        print(f"\n❌ 语音文件生成失败！")
        sys.exit(1)


if __name__ == '__main__':
    main()